package cn.pugle.ormtest.ebean;

import cn.pugle.ormtest.BaseDemo;
import cn.pugle.ormtest.ebean.domain.CustomerModel2;
import cn.pugle.ormtest.ebean.domain.OrderModel2;
import cn.pugle.ormtest.ebean.domain.dto.CustomerDetail;
import cn.pugle.ormtest.ebean.domain.query.QCustomerModel2;
import cn.pugle.ormtest.ebean.domain.query.QOrderModel2;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.ebean.EbeanServer;
import io.ebean.PagedList;
import io.ebean.Query;
import io.ebean.SqlRow;
import io.ebean.annotation.Transactional;
import io.ebean.annotation.TxType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

import static cn.pugle.ormtest.common.JSON.SNAKE_MAPPER;

/**
 * 需要装ide插件 and maven插件 ebean.mf必须, 是enhance各种用的.
 *
 * @author tzp
 * @date 2017/12/22
 */
@Service
public class EbeanDemo implements BaseDemo {
    @Autowired
    private EbeanServer ebeanServer;

    @Override
    public void create() {
        CustomerModel2 customer = new CustomerModel2();
        customer.setName("Rob");
        customer.save();

        CustomerModel2 customerModel1 = new CustomerModel2();
        customerModel1.setName("Lily");
        ebeanServer.insert(customerModel1);


        OrderModel2 order = new OrderModel2();
        order.setOrderDate(new Date());
        order.setPrice(121L);
        order.setAddress("aaaaa");

        CustomerModel2 tmpCustomer = new CustomerModel2();
        tmpCustomer.setId(10000L);

        order.setCustomer(tmpCustomer);
        order.save();
    }

    /**
     * 或许应该把这些条件拼组的代码放在finder里而不是service层
     */
    @Override
    @Transactional(type = TxType.REQUIRES_NEW)
    public void retrieve() throws JsonProcessingException {
        //use ebeanServer
        CustomerModel2 customerModel = ebeanServer.find(CustomerModel2.class, 1L);
        System.out.println(SNAKE_MAPPER.writeValueAsString(customerModel));

        //user finder
        CustomerModel2 customerModel1 = CustomerModel2.finder.byId(1L);
        System.out.println(SNAKE_MAPPER.writeValueAsString(customerModel1));

        //use query bean
        List<CustomerModel2> list = new QCustomerModel2()
                .id.greaterThan(1L)
                .findList();
        System.out.println("list: " + SNAKE_MAPPER.writeValueAsString(list));

        //like
        List<Object> ids = CustomerModel2.finder.where()
                .name.like("%Ro%")
                .findIds();
        System.out.println("like" + SNAKE_MAPPER.writeValueAsString(ids));

        //count
        int size = CustomerModel2.finder.where().findCount();
        System.out.println("count: " + size);

        //what is query?? 上面无论是 ebeanServer的find还是querybean的查找, 里面都是生成了query
        Query<CustomerModel2> query = ebeanServer.find(CustomerModel2.class);
        Query<CustomerModel2> query1 = CustomerModel2.finder.query();
//        query.order/fetch/findList
    }

    @Override
    public void update() {
        CustomerModel2 customer = CustomerModel2.finder.byId(1L);
        customer.setName("afsdafsdafsd");
        customer.update();

        CustomerModel2 ref = CustomerModel2.finder.ref(2L);//不使用除id外的字段不执行select, 但下面这行就触发select了
        ref.setName("ffffff");
        ref.update();

        CustomerModel2 updateModel = new CustomerModel2();//这个不执行select, 直接update
        updateModel.setId(3L);
        updateModel.setName("wwwww");
        updateModel.update();
    }

    @Override
    public void delete() {
        CustomerModel2 ref = CustomerModel2.finder.ref(4L);
        ref.delete();

        int delete = ebeanServer.delete(CustomerModel2.class, 6L);//级联删
        System.out.println(delete);
    }

    /**
     * 若这个方法上没有事务, 前三个sout最终执行了四条sql, 有事务只会有三条sql
     */
    @Override
    public void join() throws JsonProcessingException {
        CustomerModel2 customerModel = ebeanServer.find(CustomerModel2.class, 1L);
        System.out.println(SNAKE_MAPPER.writeValueAsString(customerModel));

        //many to one
        OrderModel2 order = ebeanServer.find(OrderModel2.class, 1L);
        System.out.println("mantoone: " + SNAKE_MAPPER.writeValueAsString(order));

        //one to many
        List<OrderModel2> orders = customerModel.getOrders();
        System.out.println("onetomany: " + SNAKE_MAPPER.writeValueAsString(orders));

        //--手动join dto
        List<CustomerDetail> customerDetails = CustomerModel2.finder.customerDetail();
        System.out.println("dto: " + SNAKE_MAPPER.writeValueAsString(customerDetails));
    }

    /**
     * 自己写sql.
     * 好像也支持用xml写?: ebean-orm.xml files and be used as a named query
     */
    @Override
    public void rawSQL() throws JsonProcessingException {
        int count = OrderModel2.finder.updatePriceByCustomerId(1L, 12345L);
        System.out.println(count);

        int count2 = OrderModel2.finder.deleteByCustomerId(2L);
        System.out.println(count2);

        List<SqlRow> sqlRows = OrderModel2.finder.recentOrders1();
        System.out.println("sqlRows: " + sqlRows.size() + SNAKE_MAPPER.writeValueAsString(sqlRows));


        List<OrderModel2> orders = OrderModel2.finder.recentOrders();
        System.out.println("orders: " + orders.size() + SNAKE_MAPPER.writeValueAsString(orders));

        //join dto的原生sql
        //CustomerModel2.finder.customerDetail();
    }

    @Override
    public void page() throws Exception {
        PagedList<CustomerModel2> page = CustomerModel2.finder.where()
                .orderBy()
                .id.desc()
                .setFirstRow(0 * 10)
                .setMaxRows(10)
                .findPagedList();

        List<CustomerModel2> list1 = page.getList();
        HashMap<String, Object> mypage = new HashMap<>();
        mypage.put("data", list1);
        mypage.put("index", page.getPageIndex());
        mypage.put("size", page.getPageSize());
        mypage.put("totalcount", page.getTotalCount());
        mypage.put("totalpage", page.getTotalPageCount());

        System.out.println("page: " + SNAKE_MAPPER.writeValueAsString(mypage));
    }

    @Override
    public void lazy() throws JsonProcessingException {
        QOrderModel2 queryBean = OrderModel2.finder.where();
        OrderModel2 one = queryBean
                .select(queryBean.id, queryBean.address)
                .id.eq(1L)
                .findOne();
        //到这时只查了id,address一次 tzpdo 但是这时我想toJson, 就又查询了全字段一次, 怎么弄?
//        System.out.println(SNAKE_MAPPER.writeValueAsString(one));

        List<OrderModel2> model2s = OrderModel2.finder.recentOrdersLazy();
        System.out.println(model2s.size());
    }

}
